home *** CD-ROM | disk | FTP | other *** search
/ Fifty: Elektronik / FIFTY Elektronik (PS_Computer_Vertrieb).iso / ps8 / fty1017 / gepackt.exe / DISK2 / PLOTSRC.EXE / WINDOWS.IMP < prev    next >
Encoding:
Text File  |  1993-11-10  |  16.5 KB  |  514 lines

  1. Type TypeBildschirm = ARRAY [1..2000] OF TypeSchirmbyte;
  2.  
  3. VAR  MonoSchirm   : TypeBildschirm ABSOLUTE $B000:0000; { Textmode }
  4.      ColorSchirm  : TypeBildschirm ABSOLUTE $B800:0000; { Textmode }
  5.  
  6. Const ColorStackPtr:Word=0;
  7.  
  8. Var ColorStack :Array[0..15] of Record
  9.                                   Tattr,
  10.                                   Efore,
  11.                                   Eback :Byte;
  12.                                  end;
  13. Const WindowStackPtr:Word=0;
  14.  
  15. Var WindowStack :Array[0..15] of Record
  16.                                    Min,
  17.                                    Max  :Word;
  18.                                    X,Y  :Integer;
  19.                                  end;
  20.  
  21. Function CalcAttr(fore,back:Byte):Byte;
  22. Var blink:Byte;
  23. begin
  24.   Blink:=(fore and 16) shl 3;
  25.   fore:=fore and 15;
  26.   back:=(back and 7) shl 4;
  27.   Calcattr:=fore or back or blink;
  28. end;
  29.  
  30. FUNCTION VideoMode:BYTE;     { Welcher Monitor ist aktiv ? }
  31.  
  32. VAR Regs : Registers;
  33.  
  34. BEGIN
  35.      WITH Regs DO BEGIN
  36.           ah := 15;          { Get Current Video State }
  37.           Intr ($10,Regs);   { Videointerrupt }
  38.           VideoMode := al;   { ah   Videomodus  }
  39.                              { 0    40*25 BW }
  40.                              { 1    40*25 Color }
  41.                              { 2    80*25 BW }
  42.                              { 3    80*25 Color }
  43.                              { 7    80*25 Monochrom Card }
  44.        END;
  45. END; { VideoMode }
  46.  
  47. Procedure IsColorMonitor;
  48. Var mode:Byte;
  49. BEGIN
  50.   Mode:=Videomode;
  51.   IsColor:= ((MEM[0064:0016] and 48 )<>48) OR (Mode IN [2,3]);
  52.   ModeCO80:=(mode=3) and Iscolor;
  53. END { IsColorMonitor } ;
  54.  
  55.  
  56. PROCEDURE MakeWindow (VAR Slide                 : WindowType;  { Window erstellen }
  57.                           Xo,Yo,Breite,Hoehe,At : BYTE;
  58.                       VAR Ok                    : INTEGER);
  59. VAR I : INTEGER;
  60. BEGIN
  61.      WITH Slide DO BEGIN
  62.           Size := succ(Breite)*succ(Hoehe)*2;  { genügend Speicher holen }
  63.           IF MemAvail <= Size THEN BEGIN    { Genügend Speicher vorhanden ? }
  64.              Ok := $FF;                        { leider Nein, also raus }
  65.              EXIT;
  66.             END ELSE Ok := 0;
  67.           GetMem (Inhalt,Size);                { Speicher holen }
  68.           Save := NIL;                         { noch kein Hintergrund }
  69.           Saved := FALSE;                      { gespeichert }
  70.           X1 := Xo;                            { obere Linke Ecke }
  71.           Y1 := Yo;                            { beim Anzeigen des Windows }
  72.           Width := Breite;                     { Breite in Zeichen }
  73.           Height := Hoehe;                     { Höhe in Zeichen }
  74.           fillchar (Inhalt^,Size,$20);         { mit Spaces füllen }
  75.           FOR I := 0 TO Pred(Size DIV 2) DO Inhalt^[I].At := At; { Attribut setzen }
  76.       END;
  77. END; { MakeWindow }
  78.  
  79. PROCEDURE GetWindow (VAR Slide              : WindowType; { Window vom }
  80.                          Xo,Yo,Breite,Hoehe : BYTE;       { Bildschirm lesen  }
  81.                      VAR Ok                 : INTEGER);
  82. VAR I,W,sW,Xy : INTEGER;
  83. BEGIN
  84.      MakeWindow (Slide,Xo,Yo,Breite,Hoehe,32,Ok);         { Window erstellen }
  85.      IF Ok<>0 THEN EXIT;                                  { Exit bei Speicherfehler }
  86.      WITH Slide DO BEGIN
  87.           W := Width*2;
  88.           sW := succ(Width);
  89.           Xy := Xo+80*pred(Yo);
  90.           If IsColor THEN
  91.              FOR I := 0 TO pred(Height) DO
  92.                  Move  (ColorSchirm[Xy+80*I],Inhalt^[I*sW].W,W)
  93.                ELSE
  94.                    FOR I := 0 TO pred(Height) DO
  95.                        Move (MonoSchirm[Xy+80*I],Inhalt^[I*sW].W,W)
  96.       END;
  97. END; { GetWindow }
  98.  
  99. PROCEDURE PutWindow (VAR Slide : Windowtype;  { Window anzeigen und Hintergrund }
  100.                      VAR Ok    : INTEGER);    { sichern }
  101. VAR I,W,Xy,sW : INTEGER;
  102. BEGIN
  103.      WITH Slide DO BEGIN
  104.          IF MemAvail <= Size THEN BEGIN
  105.              Ok := $FF;
  106.              EXIT;
  107.             END ELSE Ok := 0;
  108.           GetMem (Save,Size);                 { Speicher für Hintergrund }
  109.           W := Width*2;
  110.           sW := succ(Width);
  111.           Xy := X1+80*pred(Y1);
  112.           If IsColor THEN
  113.              FOR I := 0 TO pred(Height) DO BEGIN
  114.                  Move(ColorSchirm[Xy+80*I],Save^[I*sW].W,W);
  115.                  Move (Inhalt^[I*sW].W,ColorSchirm[Xy+80*I],W);
  116.                 END
  117.                ELSE
  118.                    FOR I := 0 TO pred(Height) DO BEGIN
  119.                        Move(MonoSchirm[Xy+80*I],Save^[I*sW].W,W);
  120.                        Move(Inhalt^[I*sW].W,MonoSchirm[Xy+80*I],W);
  121.                 END;
  122.           Saved := TRUE;
  123.         END; { WITH Slide DO }
  124. END; { PutWindow }
  125.  
  126. PROCEDURE ShowWindow (VAR Slide : Windowtype); { Anzeigen ohne sichern des }
  127. VAR I,Xy,W,sW : INTEGER;                       { Hintergrundes }
  128. BEGIN
  129.      WITH Slide DO BEGIN
  130.           W := Width*2;
  131.           sW := succ(Width);
  132.           Xy := X1+80*pred(Y1);
  133.           If IsColor THEN
  134.              FOR I := 0 TO pred(Height) DO
  135.                  Move (Inhalt^[I*sW].W,ColorSchirm[Xy+80*I],W)
  136.                ELSE
  137.                    FOR I := 0 TO pred(Height) DO
  138.                        Move (Inhalt^[I*sW].W,MonoSchirm[Xy+80*I],W)
  139.      END;
  140. END; { ShowWindow }
  141.  
  142.  
  143. PROCEDURE RestoreWindow ( VAR Slide : WindowType; { Hintergrund restaurieren }
  144.                           VAR Ok    : INTEGER);
  145. VAR I,Xy,W,sW : INTEGER;
  146. BEGIN
  147.      WITH Slide DO IF Saved THEN BEGIN
  148.           W := Width*2;
  149.           sW := succ(Width);
  150.           Xy := X1+80*pred(Y1);
  151.           If IsColor THEN
  152.              FOR I := 0 TO pred(Height) DO
  153.                  Move (Save^[I*sW].W,ColorSchirm[Xy+80*I],W)
  154.                ELSE
  155.                    FOR I := 0 TO pred(Height) DO
  156.                        Move (Save^[I*sW].W,MonoSchirm[Xy+80*I],W);
  157.           FreeMem (Save,Size);           { Speicher wieder freimachen }
  158.           Saved := False;
  159.           Ok := 0;
  160.         END
  161.        ELSE Ok := $FF; { not saved, no Restore ! }
  162. END; { RestoreWindow }
  163.  
  164. PROCEDURE WriteToWindow (VAR Slide  : WindowType;  { Beschriftung von Windows }
  165.                              X,Y,At : BYTE;
  166.                              Zeile  : Str80);
  167. VAR I : BYTE;
  168. BEGIN
  169.      WITH Slide DO BEGIN
  170.           IF Inhalt=NIL THEN EXIT;                 { gibts das Window überhaupt ? }
  171.           IF Y>(Height) THEN EXIT;                 { Zeilennummer zu groß ? }
  172.           Zeile := copy (Zeile,1,Width);           { Zeilenlänge korrigieren }
  173.           FOR I := 1 TO length(Zeile) DO
  174.               Inhalt^[pred(Y)*succ(Width)+pred(X)+pred(I)].W :=
  175.                      ord(Zeile[I]) + At SHL 8;
  176.       END;
  177. END; { WriteToWindow }
  178.  
  179. PROCEDURE MakeFrame (VAR Slide  : WindowType;      { Windows Einrahmen }
  180.                          At,Typ : BYTE);
  181.  
  182. TYPE  Koordinaten = (lo,ro,lu,ru,s,w);
  183.       FrameType = ARRAY [1..2,Koordinaten] OF CHAR;
  184. CONST Frame : FrameType = (('┌','┐','└','┘','│','─'),  { Einfach und }
  185.                            ('╔','╗','╚','╝','║','═')); { Doppelrahmen }
  186. VAR I : BYTE;
  187. BEGIN
  188.      IF (Typ<1) OR (Typ>2) THEN Typ := 1;
  189.      WITH Slide DO BEGIN
  190.           IF Inhalt=NIL THEN EXIT;
  191.           WriteToWindow (Slide,1,1,At,Frame[Typ,lo]);
  192.           WriteToWindow (Slide,Width,1,At,Frame[Typ,ro]);
  193.           WriteToWindow (Slide,1,Height,At,Frame[Typ,lu]);
  194.           WriteToWindow (Slide,Width,Height,At,Frame[Typ,ru]);
  195.           FOR I := 2 TO pred(Height) DO BEGIN
  196.               WriteToWindow (Slide,1,I,At,Frame[Typ,s]);
  197.               WriteToWindow (Slide,Width,I,At,Frame[Typ,s]);
  198.              END;
  199.           FOR I := 2 TO pred(Width) DO BEGIN
  200.               WriteToWindow (Slide,I,1,At,Frame[Typ,w]);
  201.               WriteToWindow (Slide,I,Height,At,Frame[Typ,w]);
  202.              END;
  203.       END;
  204. END; { MakeFrame }
  205.  
  206. PROCEDURE MoveWindow ( VAR Slide  : WindowType;  { Window von der aktuellen }
  207.                            X,Y    : BYTE;        { an neue Position bringen. }
  208.                        VAR Ok     : INTEGER);    { und anzeigen }
  209. BEGIN
  210.      WITH Slide DO BEGIN
  211.           IF Saved THEN BEGIN
  212.              RestoreWindow (Slide,Ok);
  213.              IF Ok<>0 THEN EXIT ELSE Ok := 0;
  214.             END;
  215.           X1 := X;
  216.           Y1 := Y;
  217.        END;
  218.      PutWindow (Slide,Ok);
  219. END; { MoveWindow }
  220.  
  221. PROCEDURE DeleteWindow ( VAR Slide : WindowType );  { Windowspeicher freigeben }
  222. BEGIN
  223.      WITH Slide DO BEGIN
  224.           IF Saved AND (Save <> NIL) THEN BEGIN
  225.              FreeMem (Save,Size);
  226.              Saved := False;
  227.              Save := NIL;
  228.             END;
  229.           IF Inhalt<>NIL THEN FreeMem (Inhalt,Size);
  230.           Inhalt := NIL;
  231.        END;
  232. END; { DeleteWindow }
  233.  
  234. PROCEDURE MakeMenue (VAR Menu          : MenueType;  { MAC Menü erstellen }
  235.                          Xo,Yo,Breite,               { Window mit Rahmen }
  236.                          Hoehe,Punkte,               { und Angabe der }
  237.                          Farbe,Balken,
  238.                          KeyCol        : BYTE;       { Auswahlmöglichkeiten }
  239.                          MenueText     : MenueTextPtr;
  240.                      VAR Ok            : INTEGER);
  241. VAR I,pt : BYTE;
  242.     S :Str80;
  243. BEGIN
  244.      WITH Menu DO BEGIN
  245.           MakeWindow (Picture,Xo,Yo,Breite,Hoehe,Farbe,Ok);
  246.           IF Ok<>0 THEN EXIT ELSE Ok := 0;
  247.           MakeFrame (Picture,Farbe,1);               { Einfacher Rand }
  248.           Items := Punkte;
  249.           Color:=Farbe;
  250.           If (Color and $F0)=0 then
  251.                   Color:=Color and $07;
  252.           LastSel:=1;
  253.           HiColor:=KeyCol;
  254.           Fillchar(HotKeys,Sizeof(HotKeys),0);
  255.           FOR I := 1 TO Items DO
  256.             begin
  257.               S:=Menuetext^[I];
  258.               Pt:=Pos('~',S);
  259.               With HotKeys[I] Do
  260.               begin
  261.                 If (Pt>0) and (Pt<Length(S)) then
  262.                 begin
  263.                   Delete(S,Pt,1);
  264.                   Key:=S[Pt];
  265.                   P:=Pt;
  266.                   Pt:=Pos('~',S);
  267.                   If (Pt>0) then
  268.                      Delete(S,Pt,1);
  269.                 end;
  270.                 S:=copy(S,1,Breite-2);
  271.                 WriteToWindow (Picture,2,1+I,Color,S);
  272.                 If Key<>#0 then
  273.                   WriteToWindow(Picture,1+P,1+I,KeyCol,Key);
  274.               end;
  275.           end;
  276.           Pcolor := Balken;
  277.        END;
  278. END; { MakeMenue }
  279.  
  280. PROCEDURE FlipLine (X,Y,At,Len : INTEGER); { Zeile auf Bildschirm umfärben }
  281. VAR I : INTEGER;                           { für den Aufbau von 'Scrollbars' }
  282.     P : INTEGER;
  283. BEGIN
  284.      Y := pred (Y) * 80;
  285.      IF IsColor THEN FOR I := X TO pred(X+Len) DO BEGIN
  286.          P := Y+I;
  287.          ColorSchirm[P].At:=At;
  288.        END
  289.       ELSE FOR I := X TO pred(X+Len) DO BEGIN
  290.                P := Y+I;
  291.                MonoSchirm[P].At := At;  { Hier ist alles simpel }
  292.              END;
  293. END; { FlipLine }
  294.  
  295.  
  296.  
  297. FUNCTION GetKey(Term:Charset):Char;    { Eine Taste lesen }
  298.    VAR Ch : CHAR;
  299.        Dummy:Integer;
  300.    BEGIN
  301.         REPEAT
  302.           Dummy:=ReadKbd(Ch);      { lesen }
  303.           Ch:=Upcase(Ch);
  304.         UNTIL Ch IN Term;
  305.         GetKey := Ch;
  306.    END; { GetKey }
  307.  
  308. FUNCTION GetMenueChoice ( VAR Menu : MenueType;         { Menü anzeigen und }
  309.                           VAR Ok   : INTEGER   ):BYTE;  { Auswahl lesen }
  310. VAR X,Y,W : BYTE;
  311.     Yl,Yh : BYTE;
  312.     Key   : Char;
  313.     OkSet :Charset;
  314.     NewSel,
  315.     I     : Integer;
  316.  
  317.    Function IsHotKey(C:Char):Byte;
  318.    Var I:Integer;
  319.    begin
  320.      IsHotKey:=0;
  321.      For I:=1 to Menu.Items do
  322.       begin
  323.         If Upcase(C)=Upcase(Menu.HotKeys[I].Key) then
  324.           begin
  325.             IsHotKey:=I;
  326.             Exit;
  327.           end;
  328.       end;
  329.    end;
  330.  
  331.  
  332. BEGIN { GetMenueChoice }
  333.      ResetMouseDelta;
  334.      FlushKbd;
  335.      WITH Menu DO BEGIN
  336.           PutWindow (Picture,Ok);                { Menü anzeigen }
  337.           IF Ok<>0 THEN EXIT ELSE Ok := 0;
  338.           Okset:=[^M,Esc,^E,^X,^Q];
  339.           For  I:=1 to Items do
  340.             With HotKeys[I] do
  341.              If Key<>#0 then
  342.               begin
  343.                 Okset:=Okset+[Upcase(Key)];
  344.               end;
  345.           Yh := succ(Picture.Y1);                { Bewegungsbereich festlegen }
  346.           If LastSel<1 then LastSel:=1;
  347.           If LastSel>Items then LastSel:=1;
  348.           Y := Yh+LastSel-1;
  349.           Yl := Yh+Items-1;
  350.           X := succ(Picture.X1);
  351.           W := Picture.Width-2;
  352.           FlipLine (X,Y,Pcolor,W);               { Erste Zeile anzeigen }
  353.           With HotKeys[Y-Picture.Y1] do
  354.             If Key<>#0 then
  355.                 FlipLine(X+P-1,Y,(HiColor and $F) or (PColor and $F0),1);
  356.           REPEAT
  357.             Key := GetKey(OkSet);{ auf Taste warten }
  358.             FlipLine (X,Y,Color,W);          { Zeile restaurieren }
  359.             With HotKeys[Y-Picture.Y1] do
  360.               If Key<>#0 then
  361.                 FlipLine(X+P-1,Y,HiColor,1);
  362.             CASE Key OF
  363.             ^E : BEGIN { Up }
  364.                       Y := pred (Y);
  365.                       IF Y<Yh THEN Y := Yl;
  366.                   END;
  367.             ^X : BEGIN { Down }
  368.                       Y := succ (Y);
  369.                       IF Y>Yl THEN Y := Yh;
  370.                   END;
  371.               END; { CASE }
  372.             FlipLine (X,Y,Pcolor,W);         { neue Zeile zeigen }
  373.             With HotKeys[Y-Picture.Y1] do
  374.               If Key<>#0 then
  375.                 FlipLine(X+P-1,Y,(HiColor and $F) or (PColor and $F0),1);
  376.           UNTIL (Key IN [^M,Esc,^Q]) or (IsHotKey(Key)>0);
  377.           Case Key of
  378.            ^M,^Q: NewSel:= Y-Picture.Y1;
  379.            Esc  : NewSel:= 0;   { oder ESC gedrückt }
  380.            ELSE NewSel:=IsHotKey(Key);
  381.           end;
  382.           If NewSel<>0 then LastSel:=NewSel;
  383.           GetMenueChoice:=NewSel;
  384.           RestoreWindow (Picture,Ok);                   { Hintergrund anzeigen }
  385.       END;
  386. END; { GetMenueChoice }
  387.  
  388. PROCEDURE DisplayString (X,Y,At:BYTE; S:Str80); { Direkt auf den Bildschirm }
  389. VAR I,L     : INTEGER;                          { schreiben }
  390.     ScrLine : ARRAY [1..80] OF TypeSchirmByte;
  391.  
  392.  
  393. BEGIN
  394.      L:=Length(S);
  395.      IF L>0 THEN BEGIN
  396.         fillchar (ScrLine,sizeof(ScrLine),At);
  397.         FOR I := 1 TO L DO ScrLine[I].Ch := S[I];
  398.         IF IsColor THEN Move (ScrLine,ColorSchirm[X+80*pred(Y)],2*L)
  399.          ELSE Move (ScrLine,MonoSchirm[X+80*pred(Y)],2*L);
  400.        END;
  401. END; { DisplayString }
  402.  
  403.  
  404. PROCEDURE DisplayInteger (X,Y,At:BYTE; Z:INTEGER; L:BYTE; Left:BOOLEAN);
  405. VAR S : STRING [10];     { Feldlänge L, Linksbündig mit Left }
  406. BEGIN
  407.   Str(Z:L,S);
  408.   IF LEFT THEN WHILE S[1]=' ' DO S := copy(S,2,length(S));
  409.      DisplayString (X,Y,At,S);
  410. END; { DisplayInteger }
  411.  
  412. PROCEDURE DisplayReal (X,Y,At:BYTE; Z:REAL; L,K:INTEGER; Left:BOOLEAN);
  413. VAR S : STRING [30];     { Feldlänge L, Nachkomma K , Linksbündig mit Left }
  414. BEGIN
  415.      str (Z:L:K,S);
  416.      IF LEFT THEN WHILE S[1]=' ' DO S := copy(S,2,length(S));
  417.      DisplayString (X,Y,At,S);
  418. END; { DisplayReal }
  419.  
  420. Procedure FullScreen;
  421. begin
  422.   Window(1,1,80,25);
  423. end;
  424.  
  425. Procedure SetEditColors(Tfore,tback,Efore,Eback:Byte);
  426.  Function Nbits(C:Byte):Integer;
  427.    Var N:Integer;
  428.  begin
  429.    N:=0;
  430.    While C<>0 do
  431.      begin
  432.        C:=C shr 1;
  433.        Inc(N,1);
  434.      end;
  435.    Nbits:=N;
  436.  end;
  437. begin
  438.   If ModeCO80 then
  439.     begin
  440.       Editforeground:=Efore;
  441.       Editbackground:=Eback;
  442.       TextColor(Tfore);
  443.       TextbackGround(Tback);
  444.     end
  445.   else
  446.      begin
  447.       If Nbits(Tfore)>Nbits(tback) then
  448.         begin
  449.           TextColor(Crt.lightgray);
  450.           TextbackGround(Crt.black);
  451.         end
  452.       else
  453.        begin
  454.         TextColor(Crt.black);
  455.         TextbackGround(Crt.lightgray);
  456.        end;
  457.       If Nbits(Efore)>Nbits(Eback) then
  458.       begin
  459.         Editforeground:=Crt.White;
  460.         Editbackground:=Crt.black;
  461.       end
  462.       else
  463.         begin
  464.           Editforeground:=Crt.Black;
  465.           Editbackground:=Crt.lightgray;
  466.         end;
  467.     end;
  468. end;
  469.  
  470. Procedure SaveColors;
  471. begin
  472.   With ColorStack[ColorStackPtr] do
  473.    begin
  474.      Tattr:=TextAttr;
  475.      Efore:=EditForeGround;
  476.      Eback:=EditBackGround;
  477.    end;
  478.   Inc(ColorStackPtr,1);
  479. end;
  480.  
  481. Procedure RestoreColors;
  482. begin
  483.   Dec(ColorStackPtr,1);
  484.   With ColorStack[ColorStackPtr] do
  485.    begin
  486.      TextAttr:=Tattr;
  487.      EditForeGround:=Efore;
  488.      EditBackGround:=Eback;
  489.    end;
  490. end;
  491.  
  492. Procedure SaveCrtWindow;
  493. begin
  494.   With WindowStack[WindowStackPtr] do
  495.    begin
  496.      X:=Crt.WhereX;
  497.      Y:=Crt.WhereY;
  498.      Min:=Crt.WindMin;
  499.      Max:=Crt.WindMax;
  500.    end;
  501.   Inc(WindowStackPtr,1);
  502. end;
  503.  
  504. Procedure RestoreCrtWindow;
  505. begin
  506.   Dec(WindowStackPtr,1);
  507.   With WindowStack[WindowStackPtr] do
  508.    begin
  509.      Crt.WindMin:=Min;
  510.      Crt.WindMax:=Max;
  511.      GotoXY(X,Y);
  512.    end;
  513. end;
  514.